# -*- coding:utf-8 -*-
# @FileName : app\services\models\moda_model.py
# @Time     : 2025/11/28
# @Author   : 天空之城
"""魔搭 模型调用封装"""
# moda_model.py
import re
import requests
from typing import List, Optional, Dict, Any
from openai import OpenAI
from openai.types.chat.chat_completion import Choice

from app.config import MODA_API_KEY, logger, MODA_MAX_RETRIES_PER_KEY

from app.services.models.base import BaseModel

class MoDaModel(BaseModel):
    
    def __init__(self, api_key: list = None, model: str = "Qwen/Qwen2.5-72B-Instruct",max_retries_per_key: int = None):
        """
        初始化 moda-千问模型

        Args:
            api_key: moda API 密钥列表
            model: 使用的模型名称，默认为 Qwen/Qwen2.5-72B-Instruct
            max_retries_per_key : 重试次数 默认 3次
        """
        # 如果没有提供api_key，则使用环境变量中的配置
        if api_key is None:
            # 从环境变量获取API密钥，支持逗号分隔的多个密钥
            api_key_str = MODA_API_KEY
            if api_key_str:
                api_key = [key.strip() for key in api_key_str.split(',')]
            else:
                api_key = []
        
        if max_retries_per_key is None:
            max_retries_per_key = MODA_MAX_RETRIES_PER_KEY
        self.api_key = api_key
        self.model = model
        self.endpoint = "https://api-inference.modelscope.cn/v1/models/"
        self.last_used_api_key_idx = 0
        self.max_retries_per_key = max_retries_per_key
        self.logger = logger

    def generate_response(self, messages: List[Dict[str, str]], tools: Optional[List[Dict[str, Any]]] = None, tool_choice: str = "auto", temperature: float = 0.1, **kwargs) -> Any:
        """
        调用 moda API 生成响应

        Args:
            system_prompt: 系统提示词
            user_prompt: 用户提示词
            temperature: 生成温度，控制随机性 (0-1)，默认0.1保证稳定性
            max_retries_per_key: 每个 key 失败前最多重试次数（可选）
        Returns:
            模型生成的响应文本
        Raises:
        Exception: 所有 key 均失败时抛出
        """
        #
        for idx, api_key in enumerate(self.api_key):
            client = OpenAI(
                base_url='https://api-inference.modelscope.cn/v1',
                api_key=api_key,
            )

            last_error = None
            for retry in range(self.max_retries_per_key + 1):
                try:
                    response = client.chat.completions.create(
                        model = self.model,
                        messages=messages,
                        tools = tools,
                        tool_choice = tool_choice,
                        temperature=temperature,
                        max_tokens=2000
                    )
                    self.last_used_api_key_idx = idx
                    # 提取模型返回的内容
                    self.logger.info("API 调用成功，使用 Key %d", idx)
                    return response.choices[0]
                except requests.exceptions.RequestException as e:
                    last_error = f"Key {idx} (attempt {retry + 1}): Request failed: {str(e)}"
                    self.logger.warning(f"API请求失败: {last_error}，重试中 ({retry+1}/{self.max_retries_per_key+1})\n")
                except KeyError as e:
                    last_error = f"Key {idx} (attempt {retry + 1}): Response parse failed: {str(e)}"
                    self.logger.error(f"API响应解析失败:{last_error},重试中 ({retry+1}/{self.max_retries_per_key+1})\n")
                except Exception as e:
                    last_error = f"Key {idx} (attempt {retry + 1}): Unknown error: {str(e)}"
                    self.logger.critical(f"未知错误:{last_error},重试中 ({retry+1}/{self.max_retries_per_key+1})\n")
                continue
            self.logger.warning("Key %d 及其重试均失败，错误: %s\n", idx, last_error)
        # 所有 key 都尝试失败
        error_msg = f"所有 API Key 均失效，最后一次错误: {last_error}\n"
        self.logger.error(error_msg)
        raise Exception(f"所有 API Key 均失效，最后一次错误: {last_error}\n") from last_error